home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-05-31 | 6.6 KB | 231 lines | [TEXT/ALFA] |
- // This may look like C code, but it is really -*- C++ -*-
- /*
- ************************************************************************
- *
- * Grayscale Image Filtration
- *
- * Declaration of functions/procedures (generally grouped together
- * under the FilterIt class umbrella) that do linear and some non-linear
- * image filtration and related transfromations. Most of the operations
- * do filtration "inplace"
- *
- * Note that class FilterIt is a friend of IMAGE, so it's privy of
- * IMAGE internals and can use them to make processing faster.
- *
- * $Id: filter.h,v 2.0 1995/03/18 18:15:48 oleg Exp oleg $
- *
- ************************************************************************
- */
-
- #ifndef __GNUC__
- #pragma once
- #endif
- #ifndef _filter_h
- #define _filter_h
-
- #ifdef __GNUC__
- #pragma interface
- #endif
-
- #include "image.h"
- #include "std.h"
-
- /*
- *------------------------------------------------------------------------
- * Convolution kernels
- *
- * Kernel coeffs are stored as rational numbers with some common denominator,
- * which can be either 1 (that is, all coeffs are ints) or power of two, or
- * some arbitrary card number. We use a family of CommonDenom classes for each
- * of those situations. Each members of the family defines how to
- * execute a division of long int by a denominator most efficiently.
- * The classes are then used in "templates" in actual filtration algorithm
- */
-
- class CommonDenomOne
- {
- public:
- inline int divide(long int x) const { return x; }
- };
-
- class over_2_up
- {
- card exponent;
- public:
- over_2_up(const card _exp) : exponent(_exp) {}
- inline int divide(long int x) const { return x>>exponent; }
- };
-
- class CommonDenom
- {
- card denom;
- public:
- CommonDenom(const card _denom) : denom(_denom) {}
- inline int divide(long int x) const { return x/(signed)denom; }
- };
- // 1D 3-point convolution kernel
- template <class Denom>
- class ConvKernel3
- {
- const int am1,a0,ap1; // a[k-1], a[k], a[k+1] coeffs
- const Denom common_denominator;
- public:
- ConvKernel3(const int _am1, const int _a0, const int _ap1,
- const Denom denom) :
- am1(_am1), a0(_a0), ap1(_ap1), common_denominator(denom) {}
- inline int convolve(const GRAY_SIGNED pm1, const GRAY_SIGNED p0,
- const GRAY_SIGNED pp1) const
- { return common_denominator.divide(pm1*am1 + p0*a0 + pp1*ap1); }
- };
-
- // Expand templates right here...
- //template class ConvKernel3<CommonDenomOne>;
-
- // Convolution kernels
- // all coeffs integers
- inline ConvKernel3<CommonDenomOne> conv_kernel(
- const int am1, const int a0, const int ap1)
- { return ConvKernel3<CommonDenomOne>(am1,a0,ap1,CommonDenomOne()); }
-
- inline ConvKernel3<over_2_up>
- conv_kernel(const int am1, const int a0, const int ap1, over_2_up denom)
- { return ConvKernel3<over_2_up>(am1,a0,ap1,denom); }
-
- inline ConvKernel3<CommonDenom>
- conv_kernel(const int am1, const int a0, const int ap1, CommonDenom denom)
- { return ConvKernel3<CommonDenom>(am1,a0,ap1,denom); }
-
-
- /*
- *------------------------------------------------------------------------
- * Look-up tables
- * to specify a mapping operation GRAY -> GRAY
- */
-
- class LookupT
- {
- friend class FilterIt;
-
- GRAY min_val, max_val; // in the GRAY domain of the mapping
- GRAY * table; // mapping itself
- card no_entries; // in the table
-
- // init the LookupT but don't fill in
- // the table
- void allocate(const GRAY _min_val, const GRAY _max_val);
-
- enum { Preallocated_no = 256 }; // Allocate ahead that many entries
- GRAY preallocated [Preallocated_no];
-
- public:
- // What to do with pixels that outside
- // [min_val,max_val] when doing mapping
- enum FringeHandling { CoerceFringes, LeaveFringes };
-
- // Just to make constructing some common
- // look-up tables sweeter...
- struct Identical { const card depth; Identical(const card _d) : depth(_d){}};
- struct MapTo {
- const GRAY from, to;
- MapTo(const GRAY _from, const GRAY _to) : from(_from), to(_to) {}
- };
- struct DownGRAY {
- const card depth_from, depth_to;
- DownGRAY(const card _f, const card _t) : depth_from(_f), depth_to(_t) {}
- };
-
-
- // Identical pixel mapping for an image of
- // specified depth
- LookupT(const Identical id);
-
- // Build a table (with one entry) to map
- // just one particular pixel
- LookupT(const MapTo map_one);
-
- // Build a table to reduce image depth from
- // one value to another (that is, build a
- // stripy table)
- LookupT(const DownGRAY downgray);
-
- LookupT(const LookupT& another); // standard assignment stuff
- LookupT& operator= (const LookupT& another);
- ~LookupT(void);
-
- // Getting hold of and/or modifying
- // specific mappings
- GRAY& operator[] (const GRAY val);
- GRAY operator[] (const GRAY val) const;
-
- // Convolve two Lookup tables, that is,
- // translate pixels of this according to
- // another table
- // (Lookup table composition)
- LookupT& apply(const LookupT& another,
- const FringeHandling fringe_handling);
-
- GRAY q_min(void) const { return min_val; }
- GRAY q_max(void) const { return max_val; }
- };
-
- inline GRAY& LookupT::operator[] (const GRAY val)
- {
- if( val < min_val || val > max_val )
- _error("The pixel value %d to look up is out of range [%d,%d]",
- val,min_val,max_val);
- return table[val-min_val];
- }
-
- inline GRAY LookupT::operator[] (const GRAY val) const
- { return (*(LookupT *)this)[val]; }
-
- /*
- *------------------------------------------------------------------------
- * The umbrella class FilterIt itself
- *
- */
-
- class FilterIt
- {
- IMAGE& image; // Image under filtration
-
- void operator=(const FilterIt&); // is not implemented, ergo, is
- // not allowed
-
- IMAGE& median_3_row(void); // 3-point row-wise filtration
- IMAGE& median_3_col(void); // 3-point col-wise filtration
- IMAGE& median_5_row(void); // 5-point row-wise filtration
- IMAGE& median_5_col(void); // 5-point col-wise filtration
- public:
-
- // How to apply filters
- enum Direction { Columns, Rows, RowsAndColumns };
-
- FilterIt(IMAGE& _image) : image(_image) {}
-
- IMAGE& median(const Direction how, const int win_size = 3);
-
- // Convolution methods
- // Templates don't work inside the class 8:(
- // ("method templates" would do, by they
- // aren't supported yet)
- #define CONV_DECL(Kernel,Denom) \
- IMAGE& conv_row(const Kernel<Denom>& kernel); \
- IMAGE& conv_col(const Kernel<Denom>& kernel); \
- IMAGE& conv(const Kernel<Denom>& kernel, \
- const Direction how = RowsAndColumns); \
-
- CONV_DECL(ConvKernel3,CommonDenomOne)
- CONV_DECL(ConvKernel3,over_2_up)
- CONV_DECL(ConvKernel3,CommonDenom)
-
- #undef CONV_DECL
-
- // Translate image pixels according to
- // the look-up table
- IMAGE& translate(const LookupT& lookupt,
- const LookupT::FringeHandling fringe_handling);
- };
-
- #endif
-